#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ping.h>
#define MAXFLDS 40     /* maximum possible number of fields */
#define MAXFLDSIZE 32   /* longest possible field + 1 = 31 byte field */
#define MAX_STRING 256

typedef char string[256];
string strs[100][100];
int i=0,j=0,count=0;

void parse( char *record, char *delim, char arr[][MAXFLDSIZE],int *fldcnt);
void print_all(int records, int pos, string name);
void print_all_macip(int records, int pos, string name);
void rep_count(int records, int pos, string verify, string name);
void check_times(int records, int posid);
void print_all_stats(int records, int pos, string name);
void count_occurrences(int records, int pos, string name, string keyword);
void check_blacklisted(int records, int pos, string name);

int main(int argc, char *argv[])
{
	char tmp[1024]={0x0};
	int fldcnt=0;
	char arr[MAXFLDS][MAXFLDSIZE]={0x0};
	int recordcnt=0;	
	
	FILE *in=fopen(argv[1],"r");         /* open file on command line */
	
	if(in==NULL)
	{
		perror("File open error");
		exit(EXIT_FAILURE);
	}
	
	fgets(tmp,sizeof(tmp),in); /*jump over header*/
	while(fgets(tmp,sizeof(tmp),in)!=0) /* read a record */
	{
	    i=0;
	    j=0;
	    recordcnt++;
		parse(tmp,",",arr,&fldcnt);    /* whack record into fields */
		for(i;i<fldcnt;i++)
		{   
			//copy all records to strs
			strcpy(strs[recordcnt-1][i],arr[i]);
		}
		
	}
	
	
	print_all_macip(recordcnt, 2,"Source devices:\n"); //list of all source devices - print mac and ip
	print_all(recordcnt, 8, "Source ports:\n"); //list of all source ports
	print_all_macip(recordcnt, 3,"\nDestination devices:\n"); //list of all destination devices - print mac and ip
	print_all(recordcnt, 9, "Destination ports:\n"); //list of all destination ports
	rep_count(recordcnt, 12, "0", "\nNº of Queries: "); //count number of queries, verifying the flag response=o
	rep_count(recordcnt, 12, "1", "\nNº of Responses: "); //count number of responses, verifying the flag response=1
	rep_count(recordcnt, 13, "3", "\nNº of Rcodes: "); //count number of Rcodes errors
	check_times(recordcnt, 10); //verify delay between question and answer
	print_all_stats(recordcnt, 2, "\nMAC source:");
	print_all_stats(recordcnt, 3, "\nMAC destination:");
	print_all_stats(recordcnt, 18, "\nNames:");
	check_blacklisted(recordcnt, 21, "\nCheck queries responses:\n");
	
	string keyword;
	printf("Insert the keyword to search in all queries: ");
	scanf("%s", keyword);
    count_occurrences(recordcnt, 18, "\nThe selected keyword:", keyword);
    
    
	fclose(in);
    return 0;	
}

//Print the MAC SRC DST and IP SRC DST
void print_all_macip(int records, int pos, string name)
{
			string strmac[records];
			string strip[records];
			string strttl[records];
			count=0;
			printf("%s", name);
			for(i=0;i<records;i++)
			{
				for(j=0;j<count;j++)
				{
					if(!strcmp(strs[i][pos],strmac[j]))
					break;
				}
				if(j==count)
				{
					strcpy(strmac[count],strs[i][pos]);
					strcpy(strip[count],strs[i][pos+4]); //More 4 to position of column IP
			        if(pos==2)
					strcpy(strttl[count],strs[i][5]); //5 is the position of column TTL			
					count++;
				}
			}
			
			for(i=0;i<count; i++)
			{
				printf("MAC:%s  - IP:%s ", strmac[i], strip[i]);
				if(pos==2)
				printf("- TTL:%s\n", strttl[i]);
				else
				printf("\n");
								
			}
			printf("");
}

//print all record of certain position - deleted the repeated records
void print_all(int records, int pos, string name)
{
			string str[records];
			count=0;
			printf("%s", name);
			for(i=0;i<records;i++)
			{
				for(j=0;j<count;j++)
				{
					if(!strcmp(strs[i][pos],str[j]))
					break;
				}
				if(j==count)
				{
					strcpy(str[count],strs[i][pos]);
					count++;
				}
			}
			
			for(i=0;i<count; i++)
			{
				printf("[%s]", str[i]);					
			}
			printf("\n");
}

//Count the occurrences of certain position
void rep_count(int records, int pos, string verify, string name)
{
	count=0;
	for(i=0; i<records; i++){ 
		if(!strcmp(strs[i][pos],verify)){
			count++;	
		}
	}
		printf("%s%d", name, count);
}

//check times between queries and answers
void check_times(int records, int posid)
{
	string dnsid[records];
	double time1, time2;
	for(i=0;i<records;i++)
	{
		for(j=0;j<count;j++)
		{
			if(!strcmp(strs[i][posid],dnsid[j]))
			break;
		}
		if(j==count)
		{
			strcpy(dnsid[count],strs[i][posid]);
			count++;
		}
	}
	printf("\n\n");
	int n;
	for(i=0;i<records;i++)
	{
		n=0;
		for(j=0;j<records;j++)
		{
			if (n==0){
				if(!strcmp(strs[j][posid], dnsid[i])){
					time1=strtod(strs[j][1], (char **) NULL);
					n=1;
				}	
			}
			if (n==1){
				if(!strcmp(strs[j][posid],dnsid[i])){
					time2=strtod(strs[j][1], (char **) NULL);
					if(time2!=time1){
					time2=strtod(strs[j][1], (char **) NULL);
					printf("DNS id: %8s - delay: %.8f\n", strs[j][posid],time2-time1);	
					}
				}
			}
			
		}
	}
}

//print all stats for certain column position
void print_all_stats(int records, int pos, string name)
{
			string names[records];
			count=0;
			float rf;
			printf("%s", name);
			for(i=0;i<records;i++)
			{
				for(j=0;j<count;j++)
				{
					if(!strcmp(strs[i][pos],names[j]))
					
					break;
				}
				if(j==count)
				{
					strcpy(names[count],strs[i][pos]);
					count++;
				}
			}
			
			float count1;
			for(i=0;i<count;i++)
			{
				for(j=0;j<records;j++)
				{
					if(!strcmp(strs[j][pos],names[i])){
					count1++;
					}
					if(j==records){
						count1=0;
						}
				}
				rf=(count1/records)*100;
				printf("\n%30s - Absolute Freq.: %2.0f - Relative Freq.: %3.2f%%", names[i], count1, rf);
				count1=0;
		    }
		    printf("\n                                                              Total: 100.00%%\n");
}

void count_occurrences(int records, int pos, string name, string keyword)
{
	int ntimes=0;
	for(i=0;i<records;i++)
	{
		if(strstr(strs[i][pos],keyword)){
			ntimes++;
		}
	}
	printf("%s (%s) appears in queries %i times.\n", name, keyword, ntimes/2);
}
 
//check if any record is at blacklist
void check_blacklisted(int records, int pos, string name)
{
	string flag="1";
	string forcheck[records];
	count=0;
	printf("%s", name);
/*			
			
*/	
	int k=0; 	
	for(k=0; k<records; k++){ 
		//printf("For 1 i=%d",i);
		if(!strcmp(strs[k][12],flag)){
		    for(i=k;i<records;i++)
			{
					for(j=0;j<count;j++)
					{
						if(!strcmp(strs[k][pos],forcheck[j])){
						break;
						}
					}
					if(j==count)
					{
						//printf("count: %d",count);
						strcpy(forcheck[count],strs[i][pos]);
						//printf("%20s\n", forcheck[count]);
						count++;
					}			
			}
		}
			
	}

			int x;
			for(x=0;x<count; x++)
			{
				printf("%4x - %24s\n", x+1, forcheck[x]);
				
			}
			
}

//parse the line with certain delim
void parse( char *record, char *delim, char arr[][MAXFLDSIZE],int *fldcnt)
{
	char*p=strtok(record,delim);
	int fld=0;//fld1=0;
	while(p)
	{
		strcpy(arr[fld],p);
		fld++;
		p=strtok('\0',delim);
	}   
	*fldcnt=fld;
}

